package com.cjk.console.service;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import com.alibaba.fastjson.JSON;
import com.cjk.console.ad.AdMng;
import com.cjk.console.enums.EventType;
import com.cjk.console.model.mqtt.AdMessage;
import com.cjk.console.request.AdRequest;
import com.cjk.foundation.commons.BusinessException;
import com.cjk.foundation.commons.response.PageResponse;
import com.cjk.foundation.commons.response.Response;
import com.cjk.foundation.dao.DeviceDao;
import com.cjk.foundation.dao.GroupDao;
import com.cjk.foundation.dao.file.AdDao;
import com.cjk.foundation.dao.file.FileModuleDao;
import com.cjk.foundation.entity.GroupEntity;
import com.cjk.foundation.entity.file.AdEntity;
import com.cjk.foundation.entity.file.FileModuleEntity;
import com.cjk.foundation.enums.ConfStatus;
import com.cjk.foundation.enums.DeviceType;
import com.cjk.foundation.enums.IsStatus;
import com.cjk.foundation.util.ZipUtil;

@Service
public class AdServiceImpl implements AdService {
	
	private final static Logger LOGGER = LoggerFactory.getLogger(AdServiceImpl.class);
	
	@Autowired
	private GroupDao groupDao;
	
	@Autowired
	private DeviceDao deviceDao;
	
	@Autowired
	private AdDao adDao;
	
	@Autowired
	private FileModuleDao fileModuleDao;
	
	@Value("${ad.templete}")
	private String adTemplete;
	
	@Autowired
	private MqttService mqttService;
	
	@Override
	public PageResponse getAdList(Integer userId, AdRequest request) {
		GroupEntity groupEntity = null;
		if (request.getGroupId() != null) {
			groupEntity = groupDao.selectById(request.getGroupId());
		} else {
			groupEntity = groupDao.selectRootGroup(userId);
		}
		List<Integer> groupIds = groupDao.selectIdsByParentId(groupEntity.getRgt(), groupEntity.getLft(), userId);
		
		List<AdEntity> adEntities = adDao.selectListByCondition(userId, groupIds, request.getPage(), request.getPageSize());
		if (CollectionUtils.isEmpty(adEntities)) {
			return PageResponse.success(0, request.getPageSize(), new ArrayList<>());
		}
		for (AdEntity adEntity : adEntities) {
			adEntity.setStatusDesc(adEntity.getStatus().getLabel());
		}
		final Integer total = adDao.selectCountByCondition(userId, groupIds);
		return PageResponse.success(total, request.getPageSize(), adEntities);
	}

	@Transactional
	@Override
	public Response delAd(AdRequest request, Integer userId) {
		if (CollectionUtils.isEmpty(request.getIds())) {
			throw new BusinessException("请至少选择一组广告");
		}
		for (Integer groupId : request.getIds()) {
			adDao.deleteById(groupId);
			fileModuleDao.deleteByGroupId(groupId);
			// 删除文件
			try {
				String baseDir = "/easyTv/data/user_" + userId + "/group_" + groupId;
				FileUtils.deleteDirectory(new File(baseDir + "/zip"));
				File file = new File(baseDir + "/hotel_service.json");
				if (file.exists()) file.delete();
			} catch (IOException e) {
				LOGGER.error(e.getMessage());
			}
		}
		return Response.success();
	}
	
	@Transactional
	@Override
	public void buildDefaultFileModule(Integer groupId) {
		
		String[] modules = {"launcherApp", "liveApp", "movieApp", "hotelZip", "hotelJson"};
		
		for (String module : modules) {
			FileModuleEntity fileModuleEntity = new FileModuleEntity();
			fileModuleEntity.setModule(module);
			fileModuleEntity.setGroupId(groupId);
			fileModuleEntity.setNeedPack(IsStatus.FALSE);
			fileModuleEntity.setNeedUpdate(IsStatus.FALSE);
			if (module.equals("launcherApp")) {
				fileModuleEntity.setDownloadUrl("http://192.168.254.1/etv/EtvLauncher.signed_v2.apk");
			}
			if (module.equals("liveApp")) {
				fileModuleEntity.setDownloadUrl("http://47.88.3.215/aoye/apk/run/imRunning1.2.0.apk");
			}
			if (module.equals("movieApp")) {
				fileModuleEntity.setDownloadUrl("http://47.88.3.215/aoye/apk/run/imRunning1.2.0.apk");
			}
			if (module.equals("hotelZip")) {
				fileModuleEntity.setFileName("service_img.zip");
				fileModuleEntity.setNeedPack(IsStatus.TRUE);
				fileModuleEntity.setDownloadUrl("http://192.168.254.1/etv/service_img.zip");
			}
			if (module.equals("hotelJson")) {
				fileModuleEntity.setFileName("hotel_service.json");
				fileModuleEntity.setDownloadUrl("http://192.168.254.1/etv/hotel_service.json");
			}
			
			fileModuleDao.insert(fileModuleEntity);
		}
	}
	
	@Transactional
	@Override
	public Response writeHotelServiceJson(AdRequest request, Integer userId) {
		getGroupEntity(request.getGroupId());
		
		String adConfContent = getAdConfContent(request.getGroupId(), userId);
		
		if (StringUtils.isEmpty(adConfContent) || !adConfContent.equals(request.getJson())) {
			final String dir = "/easyTv/data/user_" + userId + "/group_" + request.getGroupId() + "/";
			adDao.insert(request.getGroupId(), userId, ConfStatus.NOT_SYNC);
			fileModuleDao.updateStateByModule("hotelJson", request.getGroupId(), IsStatus.TRUE);
			AdMng.makeHotelServiceJson(dir, request.getJson());
		}
		
		if (!CollectionUtils.isEmpty(request.getRemoveFilePaths())) {
			for (String path : request.getRemoveFilePaths()) {
				String dir = "/easyTv/data/user_" + userId + "/group_" + request.getGroupId() + "/" + path;
				File file = new File(dir);
				if (file.exists()) file.delete();
			}
			fileModuleDao.updateStateByModule("hotelZip", request.getGroupId(), IsStatus.TRUE);
			adDao.insert(request.getGroupId(), userId, ConfStatus.NOT_SYNC);
		}

		return Response.success();
	}

	@Override
	public Response getHotelServiceJson(Integer groupId, Integer userId) {
		String adConfContent = getAdConfContent(groupId, userId);
		if (StringUtils.isEmpty(adConfContent)) {
			return Response.success(JSON.parseObject(adTemplete));
		}
		return Response.success(JSON.parseObject(adConfContent));
	}
	
	private String getAdConfContent(Integer groupId, Integer userId) {
		try {
			final String dir = "/easyTv/data/user_" + userId + "/group_" + groupId + "/";
			File file = new File(dir + "hotel_service.json");
			if (file.exists()) {
				FileReader reader = new FileReader(file);
				BufferedReader bufferedReader = new BufferedReader(reader);
				StringBuilder sb = new StringBuilder();
				String line = "";
				while ((line = bufferedReader.readLine()) != null) {
		        	sb.append(line);
		        }
				bufferedReader.close();
				return sb.toString();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	@Transactional
	@Override
	public Response confAd(Integer groupId, Integer userId) {
		
		getGroupEntity(groupId);
		
		List<String> sns = deviceDao.selectSnsByGroupIdIncSub(groupId, DeviceType.SERVER);
		
		if (CollectionUtils.isEmpty(sns)) {
			throw new BusinessException("该分组及其子分组没有服务器");
		}
			
		List<FileModuleEntity> fileModuleEntities = fileModuleDao.selectListByGroupId(groupId); 
		    
		if (CollectionUtils.isEmpty(fileModuleEntities)) {
			throw new BusinessException("没有需要更新的文件");
		}
		
		boolean needConfAd = false;
		
		final String dir = "/easyTv/data/user_" + userId + "/group_" + groupId + "/";
		
		List<String> downloadUrls = new ArrayList<>();
		
		for (FileModuleEntity fileModuleEntity : fileModuleEntities) {
			if (fileModuleEntity.getNeedUpdate().equals(IsStatus.TRUE)) {
				needConfAd = true;
				if (fileModuleEntity.getNeedPack().equals(IsStatus.TRUE)) {
					ZipUtil.makeZip(dir + fileModuleEntity.getFileName(), dir + "zip/");
				} 
				String version = AdMng.buildVersion(fileModuleEntity.getVersion());
				Integer updateTimestamp = AdMng.buildUpdateTimestamp();
				fileModuleDao.updateVersion(fileModuleEntity.getModule(), groupId, version, updateTimestamp);
				fileModuleEntity.setVersion(version);
				fileModuleEntity.setUpdateTimestamp(updateTimestamp);
				downloadUrls.add("http://101.132.161.95/file/group/" + userId + "/" + groupId + "/" + fileModuleEntity.getFileName());
			}
		}
		
		if (needConfAd) {
			adDao.conf(ConfStatus.UP_TO_DATE, new Date(), groupId);
			AdMng.makeHotelUpdateJson(dir, fileModuleEntities);
			downloadUrls.add("http://101.132.161.95/file/group/" + userId + "/" + groupId + "/hotel_update.json");
			AdMessage adMessage = new AdMessage();
			adMessage.setEventType(EventType.CONFIG_AD);
			adMessage.setPublishTime(new Date());
			for (String sn : sns) {
				AdMng.makeRootJson(sn);
				downloadUrls.add("http://101.132.161.95/file/device/" + sn + "/root.json");
				adMessage.setSn(sn);
				adMessage.setDownloadUrls(downloadUrls);
				LOGGER.info(JSON.toJSONString(adMessage));
				mqttService.publish(sn, adMessage);
			}	
			fileModuleDao.updateStateByGroupId(groupId, IsStatus.FALSE);
		} else {
			throw new BusinessException("没有需要更新的文件");
		}
		
		return Response.success();
	}
	
	private GroupEntity getGroupEntity(Integer groupId) {
		GroupEntity groupEntity = groupDao.selectById(groupId);
		if (groupEntity == null) {
			throw new BusinessException("分组不存在");
		}
		return groupEntity;
	}
}
